using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using RazorEnhanced;
using Assistant.Properties;
using System.IO;
//#import <FarmMonster.Designer.cs>


namespace Assistant.Plus.Scripts
{
    public partial class FarmMonster : Form
    {
        public static Assistant.Point3D StandbyPos = Assistant.Point3D.MinusOne;
        public static bool BackToPos = false;
        public static bool FollowTarget = false;
        public static bool ChivHeal = false;
        public static bool AutoHonor = false;
        public static bool UseEoO = false;
        public static int BodyID = 0;
        public static int Hue = 0;
        public static string MobName = "";
        public static int Range = 12;
        public static bool UseMomentum;
        public static bool UseLS;
        public static bool UseConfidence;
        public static bool UseCounterAttack;
        public static bool UseWhirlwind;
        public static bool UseConsWeap;
        public static bool UseDivineFury;
        public static bool UseCurseWeap;
        public static bool CastAfterSwing;
        public static int LowHPSet = 100;
        public static int NetDelay = 300;
        public static bool UsePrimary;
        public static bool UseSecondary;
        public static bool AttackAll;
        public static bool AllowBlue;
        public static bool AutoVamp;
        public static bool AutoLoot;
        public static bool HonorChamp;
        public static bool AutoHide;
        public static bool EoOTypeOnly;
        public static bool AutoWraith;
        public static bool AttackOtherType;
        public static bool AdjWWPos;
        public static double CurseWeapPreCastTime = 3;
        public static List<Point3D> WPList = new List<Point3D>();
        public static bool UseWP;
        public static bool PickUpGold;
        public static bool FollowMob;
        public static int FollowMobSer;
        public static string FollowMobName;
        public static int FollowMobRange;
        public static int ClearRange;
        public static int ClearCount;
        public static bool AutoStart;
        public static int WWAdjRange;
        public static bool StopWhenBloodOath;
        public static bool GoToGold;
        public static bool HideCorpse;
        public static bool HiPrioConsWeap;
        public static bool OnlyConfWhenSurrounded;
        public static int RuneBookSer;
        public static string LastLoadFile;
        public static bool WaitAtWP;
        public static bool EoOCheckOthers;
        public static bool SaveRunningState;
        public static bool Running;

        private static bool _running = false;
        private static FarmMonster _form;
        private static Thread _thread;
        private static string _pendingSpell = String.Empty;
        private static int _wpIndex = 0;
        private static bool _recordingWP;
        private static Point3D _lastRecWP;
        private static DateTime _lastTick;
        private static bool _wpReached;
        private static int _wpCount;

        public FarmMonster()
        {
            InitializeComponent();
        }
        public static void Engine()
        {
            try
            {
                while (true)
                {
                    //World.Player.SendDebugMessage(MsgLevel.Warning, "Loop Time: {0}", (DateTime.Now - _lastTick).TotalMilliseconds);
                    _lastTick = DateTime.Now;
                    //World.Player.OverheadDebugMessage(222, "Mark 1");
                    if (_form == null)
                    {
                        return;
                    }
                    if (World.Player == null)
                    {
                        continue;
                    }
                    if (_recordingWP)
                    {
                        if (Utility.Distance(World.Player.Position, _lastRecWP) >= 4)
                        {
                            _lastRecWP = World.Player.Position;
                            WPList.Add(_lastRecWP);
                            _form.listBoxWPList.Items.Add(_lastRecWP);
                        }
                        continue;
                    }
                    if (World.Player.IsGhost)
                    {
                        continue;
                    }
                    if (!_running)
                    {
                        if (World.Player != null && AutoHide && !Targeting.HasTarget && !World.Player.IsMoving && !World.Player.Buffs.Contains(BuffIcon.HidingAndOrStealth) && !World.Player.Buffs.Contains(BuffIcon.Invisibility))
                        {
                            Client.Instance.SendToServerWait(new UseSkill((ushort)SkillName.Hiding));
                            Thread.Sleep(2000);
                        }
                        Spell.ClearAutoAbility();
                        Spell.ClearAutoSpell();
                        Thread.Sleep(100);
                        continue;
                    }
                    if (World.Player == null || World.Player.IsGhost || !World.Player.Visible)
                    {
                        Spell.ClearAutoAbility();
                        Spell.ClearAutoSpell();
                        Thread.Sleep(1000);
                        continue;
                    }
                    //World.Player.OverheadDebugMessage(222, "Mark 2");
                    bool isPickingGold = false;
                    if (!World.Player.IsGhost && PickUpGold && GoToGold && !ActionQueue.InAction)
                    {
                        int count = 0;
                        foreach (Item gold in World.Items.Values)
                        {
                            if (gold.ItemID == 0xeed && Utility.InRange(World.Player.Position, gold.Position, World.Player.VisRange))
                            {
                                ++count;
                            }
                        }
                        if (count > 0)
                        {
                            World.Player.SendDebugMessage(MsgLevel.Warning, "Found {0} Gold Piles", count);
                            if (!ActionQueue.InAction)
                            {
                                int range = 1;
                                int maxCount = 0;
                                Point3D pos = World.Player.Position;
                                bool foundRich = false;
                                //while (range <= 18)
                                //{
                                //    pos = PathHelper.FindItemDensestPos(World.Player.Position, 0xeed, out maxCount, range, true, 2);
                                //    if (maxCount > 10)
                                //    {
                                //        foundRich = true;
                                //        break;
                                //    }
                                //    ++range;
                                //}
                                //if (!foundRich)
                                //{
                                //    range = 1;
                                //    while (range <= 18)
                                //    {
                                //        pos = PathHelper.FindItemDensestPos(World.Player.Position, 0xeed, out maxCount, range, true, 2);
                                //        if (maxCount > 5)
                                //        {
                                //            foundRich = true;
                                //            break;
                                //        }
                                //        ++range;
                                //    }
                                //}
                                if (!foundRich)
                                {
                                    range = 1;
                                    while (range <= 18)
                                    {
                                        pos = PathHelper.FindItemDensestPos(World.Player.Position, 0xeed, out maxCount, range, true, 1);
                                        if (maxCount > 0)
                                        {
                                            foundRich = true;
                                            break;
                                        }
                                        ++range;
                                    }
                                }
                                if (maxCount > 0)
                                {
                                    World.Player.OverheadDebugMessage(222, "Gold Around Position {0}, Count {1}", pos, maxCount);
                                    World.Player.OverheadDebugMessage(222, "Go To Gold Pos");
                                    PathHelper.GoToPosition(pos);

                                }
                            }
                        }
                    }
                    //World.Player.OverheadDebugMessage(222, "Mark 3");
                    if (AutoVamp && !World.Player.IsVampire)
                    {
                        Spell.ClearAutoAbility();
                        Spell.ClearAutoSpell();
                        if (World.Player.Mana > 20)
                        {
                            Spell.SpellHotKey("Vampiric Embrace");
                        }
                        Thread.Sleep(2000);
                        continue;
                    }
                    if (AutoWraith && World.Player.Body != 747 && World.Player.Body != 748)
                    {
                        Spell.ClearAutoAbility();
                        Spell.ClearAutoSpell();
                        if (World.Player.Mana > 20)
                        {
                            Spell.SpellHotKey("Wraith Form");
                        }
                        Thread.Sleep(2000);
                        continue;
                    }
                    //World.Player.OverheadDebugMessage(222, "Tick");
                    if (StopWhenBloodOath && World.Player.Buffs.Contains(BuffIcon.BloodOathCurse))
                    {
                        if (!SpecialMoves.CheckAvailable(AOSAbility.WhirlwindAttack) || TargetHelper.EnemyInRange(1) < 3)
                        {
                            Client.Instance.SendToServer(new SetWarMode(false));
                            Spell.RemoveCurse();
                            Thread.Sleep(250);
                            continue;
                        }
                    }
                    Mobile followMob = null;
                    if (!ActionQueue.InAction && FollowMob && FollowMobSer != 0)
                    {
                        followMob = World.FindMobile(FollowMobSer);
                        {
                            if (followMob != null && !followMob.IsGhost && !Utility.InRange(World.Player.Position, followMob.Position, FollowMobRange))
                            {
                                World.Player.OverheadDebugMessage(333, "Follow {0}", followMob.OrigName);
                                //MiscHelper.GoToPosition(followMob.Position, true);
                                PathHelper.FollowTarget(followMob, FollowMobRange / 2, true);
                            }
                        }
                    }
                    //find target to attack
                    //World.Player.SendDebugMessage(MsgLevel.Debug, "Script Loop");
                    Mobile combatant = Targeting.LastCombatant;

                    if (!isPickingGold && UseWP && WPList.Count > 0)//move to next point
                    {
                        //World.Player.OverheadDebugMessage(333, "Using WP List");
                        if (!_wpReached && Utility.InRange(World.Player.Position, WPList[_wpIndex], 2))//on wp move to next
                        {
                            World.Player.OverheadDebugMessage(333, "Arrived At Waypoint {0}", _wpIndex);
                            _wpReached = true;
                        }

                        if (_wpReached && (combatant == null || Utility.InRange(World.Player.Position, combatant.Position, ClearRange)) && TargetHelper.EnemyAroundPos(WPList[_wpIndex], ClearRange, AllowBlue) <= ClearCount)//no enemy in range of current wp
                        {
                            //if (!World.Player.IsMoving)//&& !_isMovingToWP)
                            {
                                if (++_wpIndex >= WPList.Count)
                                {
                                    _wpIndex = 0;
                                }
                                _form.listBoxWPList.SelectedIndex = _wpIndex;
                                _wpReached = false;
                                //set next wp
                                World.Player.OverheadDebugMessage(333, "Clear, Move To Next WP {0}, Distance {1}", WPList[_wpIndex], Utility.Distance(World.Player.Position, WPList[_wpIndex]));
                            }
                        }
                        if (!_wpReached && !ActionQueue.InAction && !Targeting.InCombat)//mobing to next wp
                        {
                            Point3D pos = WPList[_wpIndex];
                            PathHelper.GoToPosition(pos, false);
                        }
                    }

                    Mobile honoredTarget = Targeting.LastHonorTarget;
                    //Dont switch target when combatant in weapon range
                    if (!Targeting.InCombat || combatant == null || !Utility.InRange(World.Player.Position, combatant.Position, WeaponHelper.GetWeaponRange()))
                    {
                        //World.Player.SendDebugMessage(MsgLevel.Warning, "Attack New Target");
                        if (AutoHonor && Targeting.AttackHonoredTarget())
                        {

                        }
                        else
                        {
                            Targeting.AttackClosestTarget(Range, (!AttackAll && AttackOtherType) ? (ushort)0 : (ushort)BodyID, (AttackAll || AttackOtherType) ? (ushort)0 : (ushort)Hue, AllowBlue);
                        }
                    }
                    else
                    {
                        //World.Player.SendDebugMessage(MsgLevel.Warning, "InCombat: {0}, Combatant: {1}", Targeting.InCombat, combatant == null ? "Null" : combatant.Name);
                    }
                    if (AttackAll)
                    {
                        Targeting.AttackAllEnemies(Range, AllowBlue);
                    }

                    //no target in range
                    if (!Targeting.InCombat && TargetHelper.EnemyInRange(Range) == 0)//No combatant in range ,heal
                    {
                        //World.Player.OverheadDebugMessage(333, "No Combatant");

                        if (ChivHeal && !Looter.IsSendingItem && !Looter.IsInsuringItem && (World.Player.Hits < LowHPSet || Player.Poisoned))
                        {
                            Spell.ChivHealSelf();
                            Misc.Pause(500);
                        }
                        else
                        {
                            if (UseDivineFury && Player.StamMax - Player.Stam > 30)
                            {
                                Spell.SpellHotKey("Divine Fury");
                                Misc.Pause(500);
                            }
                            else if (UseConfidence && World.Player.Hits <= LowHPSet && !World.Player.Buffs.Contains(BuffIcon.Confidence))
                            {
                                Spell.SetAutoCastHotkey(true, "Confidence");
                                Misc.Pause(500);
                            }
                            if (!isPickingGold && BackToPos && !ActionQueue.InAction)// && !World.Player.IsMoving&&!World.Player.Paralized && StandbyPos != Assistant.Point3D.MinusOne && World.Player.Position != StandbyPos && Utility.InRange(World.Player.Position, StandbyPos, 30))
                            {
                                PathHelper.GoToPosition(StandbyPos);
                                Misc.Pause(200);
                            }
                        }
                        //World.Player.OverheadDebugMessage(333, "Try WP List");
                        continue;
                    }
                    //in combat
                    //World.Player.OverheadDebugMessage(222, "Mark 4");
                    combatant = Targeting.LastCombatant;
                    if (!isPickingGold && TargetHelper.EnemyInRange(WeaponHelper.GetWeaponRange()) < 1 && !ActionQueue.InAction)// && !World.Player.IsMoving && !World.Player.Paralized && !Utility.InRange(World.Player.Position, combatant.Position, WeaponHelper.GetWeaponRange()))
                    {
                        //World.Player.OverheadDebugMessage(222, "Mark 5");
                        if ((!WaitAtWP && UseWP && WPList.Count > 0) || followMob != null)
                        {
                            int range = followMob != null ? FollowMobRange : ClearRange;
                            Point3D centerPos = followMob != null ? followMob.Position : (UseWP ? WPList[_wpIndex] : World.Player.Position);
                            Point3D pos = PathHelper.FindMobileDensestPos(centerPos, out int maxCount, 0, range);
                            if (UseWhirlwind && maxCount > 1)
                            {
                                SpecialMoves.SetAbilityTo(AOSAbility.WhirlwindAttack);
                            }
                            if (pos != World.Player.Position)//&& (!FollowMob || followMob == null || Utility.InRange(followMob.Position, pos, FollowMobRange)))
                            {
                                World.Player.OverheadDebugMessage(333, "Move To Enemy Crowd");
                                PathHelper.GoToPosition(pos, false);
                            }
                        }
                        else if (FollowTarget && combatant != null)
                        {
                            PathHelper.FollowTarget(combatant, WeaponHelper.GetWeaponRange());
                        }
                    }
                    if (combatant == null)
                    {
                        continue;
                    }
                    //World.Player.OverheadDebugMessage(222, "Mark 6");
                    if (UseCurseWeap && (World.Player.LowerReagentCost > 70 || PlusHotKey.FindItem(World.Player.Backpack, 0xf8a) || PlusHotKey.FindItem(World.Player.Backpack, 2263)) && CurseWeapPreCastTime > 0 && (!World.Player.Buffs.Contains(BuffIcon.CurseWeapon) || BuffHelper.GetRemainingTime(BuffIcon.CurseWeapon) < TimeSpan.FromSeconds(CurseWeapPreCastTime)))
                    {
                        _pendingSpell = "Curse Weapon";
                    }
                    else if (UseConsWeap && HiPrioConsWeap && (!World.Player.Buffs.Contains(BuffIcon.ConsecrateWeapon) || BuffHelper.GetRemainingTime(BuffIcon.ConsecrateWeapon) < TimeSpan.FromSeconds(2)))
                    {
                        _pendingSpell = "Consecrate Weapon";
                    }
                    else if (UseCounterAttack && ((World.Player.Hits > LowHPSet && (!OnlyConfWhenSurrounded || TargetHelper.EnemyInRange(1) < 2)) || !UseConfidence) && !World.Player.Buffs.Contains(BuffIcon.CounterAttack))
                    {
                        Spell.SetAutoCastHotkey(true, "Counter Attack");
                    }
                    else if (UseConfidence && (World.Player.Hits <= LowHPSet || !UseCounterAttack || (OnlyConfWhenSurrounded && TargetHelper.EnemyInRange(1) > 1)) && !World.Player.Buffs.Contains(BuffIcon.Confidence))
                    {
                        Spell.SetAutoCastHotkey(true, "Confidence");
                    }
                    else if (UseEoO && (!EoOCheckOthers || TargetHelper.EnemyTypesInRange(Range) == 1) && (!World.Player.Buffs.Contains(BuffIcon.EnemyOfOne) || (combatant != null && (!EoOTypeOnly || combatant.Hue == Hue && combatant.Body == BodyID) && combatant.Notoriety != 5)))//only use EoO on selected type
                    {
                        _pendingSpell = "Enemy Of One";
                    }
                    else if (UseDivineFury && World.Player.StamMax - World.Player.Stam > 30)
                    {
                        _pendingSpell = "Divine Fury";
                    }
                    else if (UseCurseWeap && CurseWeapPreCastTime == 0 && (World.Player.LowerReagentCost > 70 || PlusHotKey.FindItem(World.Player.Backpack, 0xf8a) || PlusHotKey.FindItem(World.Player.Backpack, 2263)) && World.Player.Hits < LowHPSet && !World.Player.Buffs.Contains(BuffIcon.CurseWeapon))
                    {
                        _pendingSpell = "Curse Weapon";
                    }
                    else if (UseConsWeap && !HiPrioConsWeap && !World.Player.Buffs.Contains(BuffIcon.ConsecrateWeapon))
                    {
                        _pendingSpell = "Consecrate Weapon";
                    }
                    int enemyCount = TargetHelper.EnemyInRange(WWAdjRange, AllowBlue);
                    //adjust ww position
                    if (!FollowMob && !UseWP && !isPickingGold && combatant != honoredTarget && UseWhirlwind && AdjWWPos && enemyCount > 1)
                    {
                        Point3D pos = PathHelper.FindMobileDensestPos(World.Player.Position, out int maxCount, 0, WWAdjRange);
                        if (pos != World.Player.Position && (followMob == null || Utility.InRange(followMob.Position, pos, 8)))
                        {
                            World.Player.SendDebugMessage(MsgLevel.Warning, "{0} Monsters On Pos: {1}, CheckZ: {2}", maxCount, pos, Facet.ZTop(World.Player.Map, pos.X, pos.Y, pos.Z));
                            Plus.PathHelper.GoToPosition(pos);
                        }
                    }
                    enemyCount = TargetHelper.EnemyInRange(WeaponHelper.GetWeaponRange(), AllowBlue);
                    //World.Player.SendDebugMessage(MsgLevel.Warning, "Enemy In Range:{0}", enemyCount);
                    if (enemyCount > 1 && ((UseMomentum && World.Player.Skills[(int)SkillName.Bushido].Value >= 70) || (UseWhirlwind && SpecialMoves.CheckAvailable(AOSAbility.WhirlwindAttack))))
                    {
                        if (enemyCount == 2 && UseMomentum)
                        {
                            if (!World.Player.Buffs.Contains(BuffIcon.MomentumStrike))
                            {
                                Spell.SetAutoCastHotkey(true, "Momentum Strike");
                            }
                        }
                        else if (UseWhirlwind)
                        {
                            SpecialMoves.UseWhirlwindAttack();
                        }
                    }
                    else if (World.Player.Mana > 25 && (UsePrimary || UseSecondary))
                    {
                        if (UsePrimary)
                        {
                            SpecialMoves.SetPrimaryAbility(false);
                        }
                        else
                        {
                            SpecialMoves.SetSecondaryAbility(false);
                        }
                    }
                    else if (UseLS && !World.Player.Buffs.Contains(BuffIcon.LightningStrike))
                    {
                        Spell.SetAutoCastHotkey(true, "Lightning Strike");
                    }
                    if (!CastAfterSwing || DateTime.Now - WeaponHelper.LastSwingTime > TimeSpan.FromSeconds(5))//stop for more than 5 sec
                    {
                        CastPendingSpell();
                    }
                    Thread.Sleep(200);
                }
            }
            catch (ThreadAbortException ex)
            {
                Assistant.Engine.ReportCrash(ex);
            }
        }
        private static void CastPendingSpell()
        {
            if (_pendingSpell != null && _pendingSpell != "")
            {
                //World.Player.OverheadDebugMessage(200, "Cast Pending Spell: {0}", _pendingSpell);
                Spell.SpellHotKey(_pendingSpell);
                _pendingSpell = "";
            }
        }
        private static void OnWeaponSwing()
        {
            double margin = 80;
            if (_pendingSpell != null && _pendingSpell != "")
            {
                TimeSpan delay = WeaponHelper.GetSwingDelay() - TimeSpan.FromMilliseconds(NetDelay) + TimeSpan.FromMilliseconds(margin);//time before next swing excuted on server
                if (delay > TimeSpan.FromMilliseconds(1500))
                {
                    delay = TimeSpan.Zero;//cast now, or wait for next swing
                }
                Timer.DelayedCallback(delay, new TimerCallback(CastPendingSpell)).Start();
            }
        }
        private static void Start()
        {
            _running = true;
            int body = BodyID, hue = Hue;
            if (HonorChamp)
            {
                body = -1;
                hue = 0;
            }
            Targeting.SetAutoHonor(AutoHonor, Range, body, hue);
            Looter.LooterEnabled = AutoLoot;
            Looter.ScavengerEnabled = PickUpGold;
            IgnoreFilter.HideCorpse = HideCorpse;
        }
        public static void ToggleRunning()
        {
            if (_running)
            {
                Stop();
            }
            else
            {
                Start();
            }
            World.Player.SendMessage(MsgLevel.Force, "Script {0}", _running ? "Running" : "Stop");
        }
        private static void Stop()
        {
            _running = false;
            Spell.ClearAutoSpell();
            Spell.ClearAutoAbility();
            Targeting.SetAutoHonor(false, Range, BodyID, Hue);
            Looter.LooterEnabled = false;
            Looter.ScavengerEnabled = false;
            IgnoreFilter.HideCorpse = false;
        }
        public static void Run()
        {
            //Looter.LooterEnabled = true;
            Targeting.SetAutoHonor(AutoHonor, Range, BodyID, Hue);
            _form = new FarmMonster();
            _thread = new Thread(Engine);
            _thread.Start();
            _form.Show();
            if (AutoStart || (SaveRunningState && Running))
            {
                Start();
            }
            else
            {
                Stop();
            }
            WeaponHelper.OnSwingAction += OnWeaponSwing;
            try
            {
                while (_form != null)
                {
                    Application.DoEvents();
                }
            }
            catch (Exception ex)
            {
                //Assistant.Engine.ReportCrash(ex);
            }
        }
        public static void Exit()
        {
            if (_form != null)
            {
                _form.Close();
            }
        }

        private void FarmMonster_Load(object sender, EventArgs e)
        {
            //init
            CheckForIllegalCrossThreadCalls = false;
            ScriptHelper.LoadConfig(this);
            updateConfigDisplay();
        }
        private void updateConfigDisplay()
        {
            Text = World.Player.OrigName + " - " + Language.GetFormName(this);
            notifyIconTray.Text = Text;
            notifyIconTray.Icon = Icon;
            textBoxRange.Text = Range.ToString();
            textBoxBody.Text = BodyID.ToString();
            textBoxHue.Text = Hue.ToString();
            textBoxStandByPos.Text = StandbyPos.ToString();
            checkBoxAutoHonor.Checked = AutoHonor;
            checkBoxBackToPos.Checked = BackToPos;
            checkBoxConfidence.Checked = UseConfidence;
            checkBoxConsWeap.Checked = UseConsWeap;
            checkBoxCounterAttack.Checked = UseCounterAttack;
            checkBoxDivineFury.Checked = UseDivineFury;
            checkBoxFollow.Checked = FollowTarget;
            checkBoxEoO.Checked = UseEoO;
            checkBoxWW.Checked = UseWhirlwind;
            checkBoxCurseWeap.Checked = UseCurseWeap;
            checkBoxLS.Checked = UseLS;
            textBoxLowHP.Text = LowHPSet.ToString();
            checkBoxCastAfterSwing.Checked = CastAfterSwing;
            textBoxNetDelay.Text = NetDelay.ToString();
            checkBoxAttackAll.Checked = AttackAll;
            checkBoxAllowBLue.Checked = AllowBlue;
            checkBoxPrimary.Checked = UsePrimary;
            checkBoxSecondary.Checked = UseSecondary;
            checkBoxAutoVamp.Checked = AutoVamp;
            checkBoxAutoLoot.Checked = AutoLoot;
            checkBoxHonorChamp.Checked = HonorChamp;
            checkBoxMomentum.Checked = UseMomentum;
            checkBoxChivHeal.Checked = ChivHeal;
            checkBoxAutoHide.Checked = AutoHide;
            checkBoxTypeOnly.Checked = EoOTypeOnly;
            checkBoxAutoWraith.Checked = AutoWraith;
            checkBoxAttackOtherType.Checked = AttackOtherType;
            checkBoxAdjWWPos.Checked = AdjWWPos;
            textBoxCurseWeaponPreCastTime.Text = CurseWeapPreCastTime.ToString();
            checkBoxUseWP.Checked = UseWP;
            checkBoxPickUpGold.Checked = PickUpGold;
            checkBoxFollowMob.Checked = FollowMob;
            textBoxFollowMobName.Text = FollowMobName;
            textBoxFollowMobRange.Text = FollowMobRange.ToString();
            listBoxWPList.Items.Clear();
            foreach (Point3D pt in WPList)
            {
                listBoxWPList.Items.Add(pt.ToString());
            }
            if (listBoxWPList.Items.Count > 0)
            {
                listBoxWPList.SelectedIndex = 0;
            }
            checkBoxAutoStart.Checked = AutoStart;
            textBoxClearCount.Text = ClearCount.ToString();
            textBoxClearRange.Text = ClearRange.ToString();
            textBoxWWAdjRange.Text = WWAdjRange.ToString();
            checkBoxStopWhenBO.Checked = StopWhenBloodOath;
            checkBoxGoToGold.Checked = GoToGold;
            checkBoxHideCorpse.Checked = HideCorpse;
            checkBoxHiPrioConsWeap.Checked = HiPrioConsWeap;
            checkBoxOnlyConfWhenSurrounded.Checked = OnlyConfWhenSurrounded;
            labelConfigName.Text = LastLoadFile;
            checkBoxWaitAtWP.Checked = WaitAtWP;
            checkBoxEoOCheckOthers.Checked = EoOCheckOthers;
            checkBoxSaveRunningState.Checked = SaveRunningState;
            LoadRuneLocList();
        }
        private void buttonSetType_Click(object sender, EventArgs e)
        {
            Targeting.OneTimeTarget(new Targeting.TargetResponseCallback(OnSetTypeTarget));
        }

        private void OnSetTypeTarget(bool location, Serial serial, Point3D p, ushort gfxid)
        {
            if (!location)
            {
                if (serial.IsMobile)
                {
                    Mobile mob = World.FindMobile(serial);
                    if (mob != null)
                    {
                        BodyID = mob.Body;
                        Hue = mob.Hue;
                        MobName = mob.Name;
                        textBoxBody.Text = BodyID.ToString();
                        textBoxHue.Text = Hue.ToString();
                        int body = BodyID, hue = Hue;
                        if (HonorChamp)
                        {
                            body = -1;
                            hue = 0;
                        }
                        Targeting.SetAutoHonor(AutoHonor && _running, Range, body, hue);
                    }
                }
            }
        }

        private void FarmMonster_FormClosed(object sender, FormClosedEventArgs e)
        {
            Running = _running;
            Stop();
            ScriptHelper.SaveConfig(this);
            WeaponHelper.OnSwingAction -= OnWeaponSwing;
            //if (_thread != null)
            //{
            //    _thread.Abort();
            //}
            _form = null;
        }

        private void checkBoxAutoHonor_CheckedChanged(object sender, EventArgs e)
        {
            AutoHonor = checkBoxAutoHonor.Checked;
            int body = BodyID, hue = Hue;
            if (HonorChamp)
            {
                body = -1;
                hue = 0;
            }
            Targeting.SetAutoHonor(AutoHonor && _running, Range, body, hue);
        }

        private void checkBoxFollow_CheckedChanged(object sender, EventArgs e)
        {
            FollowTarget = checkBoxFollow.Checked;
        }

        private void checkBoxBackToPos_CheckedChanged(object sender, EventArgs e)
        {
            BackToPos = checkBoxBackToPos.Checked;
        }

        private void buttonSetPos_Click(object sender, EventArgs e)
        {
            StandbyPos = World.Player.Position;
            textBoxStandByPos.Text = StandbyPos.ToString();
        }

        private void checkBoxWW_CheckedChanged(object sender, EventArgs e)
        {
            UseWhirlwind = checkBoxWW.Checked;
        }

        private void checkBoxConsWeap_CheckedChanged(object sender, EventArgs e)
        {
            UseConsWeap = checkBoxConsWeap.Checked;
        }

        private void checkBoxConfidence_CheckedChanged(object sender, EventArgs e)
        {
            UseConfidence = checkBoxConfidence.Checked;
        }

        private void checkBoxDivineFury_CheckedChanged(object sender, EventArgs e)
        {
            UseDivineFury = checkBoxDivineFury.Checked;
        }

        private void checkBoxEoO_CheckedChanged(object sender, EventArgs e)
        {
            UseEoO = checkBoxEoO.Checked;
        }

        private void textBoxRange_TextChanged(object sender, EventArgs e)
        {
            if (!int.TryParse(textBoxRange.Text, out Range))
            {
                textBoxRange.Text = Range.ToString();
                Targeting.SetAutoHonor(AutoHonor, Range, BodyID, Hue);
            }
            int body = BodyID, hue = Hue;
            if (HonorChamp)
            {
                body = -1;
                hue = 0;
            }
            Targeting.SetAutoHonor(AutoHonor && _running, Range, body, hue);
        }

        private void textBoxBody_TextChanged(object sender, EventArgs e)
        {
            if (!int.TryParse(textBoxBody.Text, out BodyID))
            {
                textBoxBody.Text = BodyID.ToString();
            }
            int body = BodyID, hue = Hue;
            if (HonorChamp)
            {
                body = -1;
                hue = 0;
            }
            Targeting.SetAutoHonor(AutoHonor && _running, Range, body, hue);
        }

        private void textBoxHue_TextChanged(object sender, EventArgs e)
        {
            if (!int.TryParse(textBoxHue.Text, out Hue))
            {
                textBoxHue.Text = Hue.ToString();
            }
            int body = BodyID, hue = Hue;
            if (HonorChamp)
            {
                body = -1;
                hue = 0;
            }
            Targeting.SetAutoHonor(AutoHonor && _running, Range, body, hue);
        }

        private void checkBoxLS_CheckedChanged(object sender, EventArgs e)
        {
            UseLS = checkBoxLS.Checked;
        }

        private void buttonClose_Click(object sender, EventArgs e)
        {
            _form.Close();
        }

        private void checkBoxCurseWeap_CheckedChanged(object sender, EventArgs e)
        {
            UseCurseWeap = checkBoxCurseWeap.Checked;
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            Start();
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            Stop();
        }

        private void checkBoxMomentum_CheckedChanged(object sender, EventArgs e)
        {
            UseMomentum = checkBoxMomentum.Checked;
        }

        private void checkBoxCastAfterSwing_CheckedChanged(object sender, EventArgs e)
        {
            CastAfterSwing = checkBoxCastAfterSwing.Checked;
        }

        private void textBoxLowHP_TextChanged(object sender, EventArgs e)
        {
            if (!int.TryParse(textBoxLowHP.Text, out LowHPSet))
            {
                textBoxLowHP.Text = LowHPSet.ToString();
            }
        }

        private void textBoxNetDelay_TextChanged(object sender, EventArgs e)
        {
            if (!int.TryParse(textBoxNetDelay.Text, out NetDelay))
            {
                textBoxNetDelay.Text = NetDelay.ToString();
            }
        }

        private void checkBoxChivHeal_CheckedChanged(object sender, EventArgs e)
        {
            ChivHeal = checkBoxChivHeal.Checked;
        }

        private void checkBoxPrimary_CheckedChanged(object sender, EventArgs e)
        {
            //World.Player.SendDebugMessage(MsgLevel.Debug, "Primary chacked changed");
            UsePrimary = checkBoxPrimary.Checked;
            if (UsePrimary)
            {
                checkBoxSecondary.Checked = false;
                UseSecondary = false;
            }
        }

        private void checkBoxSecondary_CheckedChanged(object sender, EventArgs e)
        {
            //World.Player.SendDebugMessage(MsgLevel.Debug, "Secondary chacked changed");
            UseSecondary = checkBoxSecondary.Checked;
            if (UseSecondary)
            {
                checkBoxPrimary.Checked = false;
                UsePrimary = false;
            }
        }

        private void checkBoxAttackAll_CheckedChanged(object sender, EventArgs e)
        {
            AttackAll = checkBoxAttackAll.Checked;
        }

        private void checkBoxAllowBLue_CheckedChanged(object sender, EventArgs e)
        {
            AllowBlue = checkBoxAllowBLue.Checked;
        }

        private void checkBoxAutoVamp_CheckedChanged(object sender, EventArgs e)
        {
            AutoVamp = checkBoxAutoVamp.Checked;
            if (AutoVamp)
            {
                checkBoxAutoWraith.Checked = false;
                AutoWraith = false;
            }
        }

        private void checkBoxCounterAttack_CheckedChanged(object sender, EventArgs e)
        {
            UseCounterAttack = checkBoxCounterAttack.Checked;
        }

        private void checkBoxAutoLoot_CheckedChanged(object sender, EventArgs e)
        {
            AutoLoot = checkBoxAutoLoot.Checked;
            Looter.LooterEnabled = AutoLoot;
        }

        private void checkBoxHonorChamp_CheckedChanged(object sender, EventArgs e)
        {
            HonorChamp = checkBoxHonorChamp.Checked;
            int body = BodyID, hue = Hue;
            if (HonorChamp)
            {
                body = -1;
                hue = 0;
            }
            Targeting.SetAutoHonor(AutoHonor && _running, Range, body, hue);
        }

        private void checkBoxAutoHide_CheckedChanged(object sender, EventArgs e)
        {
            AutoHide = checkBoxAutoHide.Checked;
        }

        private void checkBoxTypeOnly_CheckedChanged(object sender, EventArgs e)
        {
            EoOTypeOnly = checkBoxTypeOnly.Checked;
        }

        private void buttoClearType1_Click(object sender, EventArgs e)
        {
            BodyID = 0;
            Hue = 0;
            textBoxBody.Text = BodyID.ToString();
            textBoxHue.Text = Hue.ToString();
            int body = BodyID, hue = Hue;
            if (HonorChamp)
            {
                body = -1;
                hue = 0;
            }
            Targeting.SetAutoHonor(AutoHonor && _running, Range, body, hue);
        }

        private void checkBoxAutoWraith_CheckedChanged(object sender, EventArgs e)
        {
            AutoWraith = checkBoxAutoWraith.Checked;
            if (AutoWraith)
            {
                checkBoxAutoVamp.Checked = false;
                AutoVamp = false;
            }
        }

        private void checkBoxAttackOtherType_CheckedChanged(object sender, EventArgs e)
        {
            AttackOtherType = checkBoxAttackOtherType.Checked;
        }

        private void checkBoxAdjWWPos_CheckedChanged(object sender, EventArgs e)
        {
            AdjWWPos = checkBoxAdjWWPos.Checked;
        }

        private void notifyIconTray_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Show();
            WindowState = FormWindowState.Normal;
            BringToFront();
        }

        private void FarmMonster_SizeChanged(object sender, EventArgs e)
        {
            Text = World.Player.OrigName + " - " + Language.GetFormName(this);
            notifyIconTray.Text = Text;
            if (WindowState == FormWindowState.Minimized)
            {
                Hide();
                ShowInTaskbar = false;
            }
            else
            {
                ShowInTaskbar = true;
            }
        }

        private void textBoxCurseWeaponPreCastTime_TextChanged(object sender, EventArgs e)
        {
            double oldValue = CurseWeapPreCastTime;
            if (Double.TryParse(textBoxCurseWeaponPreCastTime.Text, out CurseWeapPreCastTime))
            {
                if (CurseWeapPreCastTime < 0)
                {
                    textBoxCurseWeaponPreCastTime.Text = oldValue.ToString();
                    CurseWeapPreCastTime = oldValue;
                }
            }
            else
            {
                textBoxCurseWeaponPreCastTime.Text = oldValue.ToString();
            }
        }

        private void buttonAddPos_Click(object sender, EventArgs e)
        {
            if (!WPList.Contains(World.Player.Position))
            {
                WPList.Add(World.Player.Position);
                listBoxWPList.SelectedIndex = listBoxWPList.Items.Add(World.Player.Position.ToString());
            }
        }

        private void checkBoxUseWP_CheckedChanged(object sender, EventArgs e)
        {
            UseWP = checkBoxUseWP.Checked;
            if (UseWP)
            {
                findNearestWPIndex();
                checkBoxFollowMob.Checked = false;
                FollowMob = false;
            }
        }

        private void findNearestWPIndex()
        {
            if (UseWP && WPList.Count > 0)
            {
                //find closest wp to set curren
                double minDist = Utility.DistanceSqrt(World.Player.Position, WPList[0]);
                int index = 0;
                foreach (Point3D p in WPList)
                {
                    double dist = Utility.DistanceSqrt(World.Player.Position, p);
                    if (dist < minDist)
                    {
                        minDist = dist;
                        _wpIndex = index;
                    }
                    ++index;
                }
            }
        }

        private void buttonRemoveWP_Click(object sender, EventArgs e)
        {
            if (listBoxWPList.SelectedIndex != -1)
            {
                WPList.RemoveAt(listBoxWPList.SelectedIndex);
                listBoxWPList.Items.RemoveAt(listBoxWPList.SelectedIndex);
            }
            if (listBoxWPList.Items.Count > 0)
            {
                listBoxWPList.SelectedIndex = 0;
            }
        }

        private void buttonClearWP_Click(object sender, EventArgs e)
        {
            WPList.Clear();
            listBoxWPList.Items.Clear();
        }

        private void buttonRecordWP_Click(object sender, EventArgs e)
        {
            _recordingWP = !_recordingWP;
            if (_recordingWP)
            {
                buttonRecordWP.Text = "Stop";
                _lastRecWP = World.Player.Position;
            }
            else
            {
                buttonRecordWP.Text = "Record";
            }
        }

        private void checkBoxPickUpGold_CheckedChanged(object sender, EventArgs e)
        {
            PickUpGold = checkBoxPickUpGold.Checked;
            Looter.ScavengerEnabled = PickUpGold;
        }

        private void checkBoxFollowMob_CheckedChanged(object sender, EventArgs e)
        {
            FollowMob = checkBoxFollowMob.Checked;
            if (FollowMob)
            {
                checkBoxUseWP.Checked = false;
                UseWP = false;
            }
        }

        private void buttonSetFollow_Click(object sender, EventArgs e)
        {
            Targeting.OneTimeTarget(new Targeting.TargetResponseCallback(OnSetFollowMob));
        }

        private void OnSetFollowMob(bool location, Serial serial, Point3D p, ushort gfxid)
        {
            if (serial.IsMobile)
            {
                Mobile mob = World.FindMobile(serial);
                if (mob != null && mob != World.Player)
                {
                    FollowMobSer = mob.Serial;
                    textBoxFollowMobName.Text = mob.Name;
                    FollowMobName = mob.OrigName;
                }
            }
        }

        private void textBoxClearCount_TextChanged(object sender, EventArgs e)
        {
            if (int.TryParse(textBoxClearCount.Text, out int clearCount))
            {
                if (clearCount < 0)
                {
                    textBoxClearCount.Text = ClearCount.ToString();
                }
                else
                {
                    ClearCount = clearCount;
                }
            }
            else
            {
                textBoxClearCount.Text = ClearCount.ToString();
            }
        }

        private void textBoxClearRange_TextChanged(object sender, EventArgs e)
        {
            if (int.TryParse(textBoxClearRange.Text, out int clearRange))
            {
                if (clearRange < 0)
                {
                    textBoxClearRange.Text = ClearRange.ToString();
                }
                else
                {
                    ClearRange = clearRange;
                }
            }
            else
            {
                textBoxClearRange.Text = ClearRange.ToString();
            }
        }

        private void textBoxFollowMobRange_TextChanged(object sender, EventArgs e)
        {
            if (int.TryParse(textBoxFollowMobRange.Text, out int followMobRange))
            {
                if (followMobRange < 0)
                {
                    textBoxFollowMobRange.Text = ClearRange.ToString();
                }
                else
                {
                    FollowMobRange = followMobRange;
                }
            }
            else
            {
                textBoxFollowMobRange.Text = FollowMobRange.ToString();
            }
        }

        private void checkBoxAutoStart_CheckedChanged(object sender, EventArgs e)
        {
            AutoStart = checkBoxAutoStart.Checked;
        }

        private void textBoxWWAdjRange_TextChanged(object sender, EventArgs e)
        {
            if (int.TryParse(textBoxWWAdjRange.Text, out int wwAdjRange))
            {
                if (wwAdjRange < 0)
                {
                    textBoxWWAdjRange.Text = WWAdjRange.ToString();
                }
                else
                {
                    WWAdjRange = wwAdjRange;
                }
            }
            else
            {
                textBoxWWAdjRange.Text = WWAdjRange.ToString();
            }
        }

        private void checkBoxStopWhenBO_CheckedChanged(object sender, EventArgs e)
        {
            StopWhenBloodOath = checkBoxStopWhenBO.Checked;
        }

        private void checkBoxGoToGold_CheckedChanged(object sender, EventArgs e)
        {
            GoToGold = checkBoxGoToGold.Checked;
        }

        private void checkBoxHideCorpse_CheckedChanged(object sender, EventArgs e)
        {
            HideCorpse = checkBoxHideCorpse.Checked;
            IgnoreFilter.HideCorpse = HideCorpse;
        }

        private void checkBoxHiPrioConsWeap_CheckedChanged(object sender, EventArgs e)
        {
            HiPrioConsWeap = checkBoxHiPrioConsWeap.Checked;
        }

        private void checkBoxOnlyConfWhenSurrounded_CheckedChanged(object sender, EventArgs e)
        {
            OnlyConfWhenSurrounded = checkBoxOnlyConfWhenSurrounded.Checked;
        }

        private void buttonSetRuneBook_Click(object sender, EventArgs e)
        {
            Targeting.OneTimeTarget(new Targeting.TargetResponseCallback(OnSetRuneBookTarget));
        }

        private void OnSetRuneBookTarget(bool location, Serial serial, Point3D p, ushort gfxid)
        {
            if (!location)
            {
                if (serial.IsItem)
                {
                    Item runeBook = World.FindItem(serial);
                    if (runeBook != null && runeBook.ItemID == 0x22c5)
                    {
                        RuneBookSer = serial;
                        LoadRuneLocList();
                    }
                }
            }
        }

        private void LoadRuneLocList()
        {
            listBoxRuneList.Items.Clear();
            Item runeBook = World.FindItem(RuneBookSer);
            if (runeBook != null && runeBook.ItemID == 0x22c5)
            {
                PlayerData.DoubleClick(runeBook);
                if (Gumps.WaitForGump(1431013363, 5000))
                {
                    if (TravelHelper.CurRuneBook.LocCount > 0)
                    {
                        foreach (string loc in TravelHelper.CurRuneBook.NameList)
                        {
                            if (loc != null && loc != string.Empty)
                            {
                                listBoxRuneList.Items.Add(loc);
                            }
                        }
                    }
                }
            }
        }

        private void buttonReloadLoc_Click(object sender, EventArgs e)
        {
            LoadRuneLocList();
        }

        private void buttonSaveConfig_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Script Config Files(*.cfg)|*.cfg";
            saveFileDialog.InitialDirectory = Assistant.Engine.RootPath;
            saveFileDialog.AddExtension = true;
            saveFileDialog.RestoreDirectory = true;
            saveFileDialog.ShowHelp= true;
            saveFileDialog.FileName = LastLoadFile;
            //saveFileDialog.CreatePrompt = true;
            saveFileDialog.OverwritePrompt = true;
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                ScriptHelper.SaveConfig(_form, saveFileDialog.FileName);
                LastLoadFile = Path.GetFileNameWithoutExtension(saveFileDialog.FileName);
                labelConfigName.Text = LastLoadFile;
            }
        }

        private void buttonLoadConfig_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Script Config Files(*.cfg)|*.cfg";
            openFileDialog.InitialDirectory = Assistant.Engine.RootPath;
            openFileDialog.RestoreDirectory = true;
            openFileDialog.ShowHelp = true;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                ScriptHelper.LoadConfig(_form, openFileDialog.FileName);
                //ScriptHelper.SaveConfig(_form);
                _form.updateConfigDisplay();
                LastLoadFile = Path.GetFileNameWithoutExtension(openFileDialog.FileName);
                labelConfigName.Text = LastLoadFile;
            }
        }

        private void buttonClearRuneBook_Click(object sender, EventArgs e)
        {
            RuneBookSer = 0;
            listBoxRuneList.Items.Clear();
        }

        private void checkBoxWaitAtWP_CheckedChanged(object sender, EventArgs e)
        {
            WaitAtWP = checkBoxWaitAtWP.Checked;
        }

        private void checkBoxEoOCheckOthers_CheckedChanged(object sender, EventArgs e)
        {
            EoOCheckOthers = checkBoxEoOCheckOthers.Checked;
        }

        private void checkBoxSaveRunningState_CheckedChanged(object sender, EventArgs e)
        {
            SaveRunningState = checkBoxSaveRunningState.Checked;
        }
    }
}
